package org.xxpay.pay.task;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.entity.PayDivisionRecord;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.DivisionInterface;
import org.xxpay.pay.service.CommonService;
import org.xxpay.pay.util.SpringUtil;

import java.util.List;

/**
 * 收款订单分账业务-定时任务
 */
@Component
public class PayDivisionScheduled extends ReissuceBase {

    @Autowired
    private CommonService commonService;

    private static final MyLog _log = MyLog.getLog(PayDivisionScheduled.class);

    /**
     * 支付订单批量补单任务
     */
    @Scheduled(cron="0 0/1 * * * ?") //每 【1分钟】执行一次
    public void division() {

        //查询出 | 支付成功&收款类订单&需要分账&分账状态为‘未分账’
        List<PayOrder> result = commonService.payOrderService.selectDivisionOrder();
        _log.info("查询出需要分账的订单条数：{}", result.size());
        for(PayOrder order: result){

            if(!checkAtomicity(order)) continue; //校验失败，本次不执行。

            String payOrderId = order.getPayOrderId();
            String channelName = order.getChannelType();
            try {
                DivisionInterface divisionInterface = (DivisionInterface) SpringUtil.getBean(channelName.toLowerCase() +  "DivisionService");
                PayDivisionRecord updateRecord = divisionInterface.division(order);

                if(updateRecord == null) continue;
                commonService.payDivisionRecordService.updateByOrderId(payOrderId, updateRecord);
            }catch (BeansException e) {
                _log.error(e, "分账失败！分账渠道类型[payOrderId = {}, channelName={}]异常", payOrderId, channelName);
                continue;
            }
        }
    }

    /**
     * 检验订单原子性
     * 1. 匹配分账条数是否一致
     * 2. 匹配分账数据是否准确
     * @return
     */
    private boolean checkAtomicity(PayOrder payOrder){

        int count = 2; //商户分账数据， 平台分账数据

        if(payOrder.getAgentId() != null) count ++;
        if(payOrder.getParentAgentId() != null && payOrder.getParentAgentId() != 0) count ++;

        List<PayDivisionRecord> list = commonService.payDivisionRecordService.selectByPayOrderId(payOrder.getPayOrderId());

        if(list.size() != count){
            _log.error("订单分账数据校验失败， 分账数量不匹配！, payOrderId = {}", payOrder.getPayOrderId());
            return false;
        }

        long totalAmount = 0L;
        for(PayDivisionRecord record : list){

            if(StringUtils.isEmpty(record.getChannelMchId())){
                _log.error("订单分账数据校验失败， channelMchId is null, payOrderId = {}", payOrder.getPayOrderId());
                return false;
            }
            totalAmount += record.getDivisionAmount();
        }

        if((totalAmount + payOrder.getChannelCost()) != payOrder.getAmount() ){
            _log.error("订单分账数据校验失败， 分账金额与订单金额不匹配, payOrderId = {}", payOrder.getPayOrderId());
            return false;
        }

        return true;
    }

}
